package com.ys.service.finance.impl;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ys.dto.AddDto;
import com.ys.dto.EditDto;
import com.ys.entity.finance.TcwWanliCnyPayment;
import com.ys.entity.finance.TcwWanliCnyPaymentItem;
import com.ys.entity.flow.YspModel;
import com.ys.entity.sys.TsUserChange;
import com.ys.entity.sys.YsMenu;
import com.ys.entity.sys.YsProcInst;
import com.ys.enume.finance.PaymentEnum;
import com.ys.enume.flow.FlowEnum;
import com.ys.enume.flow.YsProcInstEnum;
import com.ys.mapper.finance.FinanceMapper;
import com.ys.mapper.finance.TcwWanliCnyPaymentItemMapper;
import com.ys.mapper.finance.TcwWanliCnyPaymentMapper;
import com.ys.service.finance.TcwWanliCnyPaymentService;
import com.ys.service.finance.TcwWanliPayoutService;
import com.ys.service.flow.YspTaskService;
import com.ys.util.shiro.ShiroUtils;
import com.ys.vo.Flow;
import com.ys.vo.R;

@Service("tcwWanliCnyPaymentService")
public class TcwWanliCnyPaymentServiceImpl implements TcwWanliCnyPaymentService {

	@Autowired
	private FinanceMapper financeMapper;
	@Autowired
	private TcwWanliCnyPaymentMapper tcwWanliCnyPaymentMapper;
	@Autowired
	private TcwWanliCnyPaymentItemMapper tcwWanliCnyPaymentItemMapper;
	
	@Autowired
	private YspTaskService yspTaskService;
	@Autowired
	private TcwWanliPayoutService tcwWanliPayoutService;
	/**
	 * 新增
	 * @param params
	 * @return
	 * @throws Exception
	 */
	@Override
	public R add(String bid, String depositPlatformCode, Integer drawingType, String remark, String detailArr, Long menuId) throws Exception {

		if (bid == null || bid.length() == 0) {
			return R.error("单号不能为空");
		} else if(new TcwWanliCnyPayment().setBid(bid).count() > 0) {
			return R.error("单号已存在");
		}
		
		/*
		 *  验证详情数据物料
		 *  1、公司编码不能为空
		 *  2、合作商银行账号不能为空
		 *  3、汇出币种不能为空
		 *  4、汇入币种不能为空
		 *  5、汇出金额不能低于50
		 *  6、汇入金额不能为空
		 */
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			String vgsbm = detailJO.getString("vgsbm");
			if (vgsbm == null || vgsbm.length() == 0) {
				return R.error("公司编码不能为空");
			}
			String partnerBankInfoVid = detailJO.getString("partnerBankInfoVid");
			if (partnerBankInfoVid == null || partnerBankInfoVid.length() == 0) {
				return R.error("合作商银行账号不能为空");
			}
			String currencyCodeOut = detailJO.getString("currencyCodeOut");
			if (currencyCodeOut == null || currencyCodeOut.length() == 0) {
				return R.error("汇出币种不能为空");
			}
			String currencyCodeIn = detailJO.getString("currencyCodeIn");
			if (currencyCodeIn == null || currencyCodeIn.length() == 0) {
				return R.error("汇入币种不能为空");
			}
			BigDecimal amountOut = detailJO.getBigDecimal("amountOut");
			if (amountOut == null) {
				return R.error("汇出金额不能为空");
			} else if (amountOut.compareTo(new BigDecimal(50)) < 0) {
				return R.error("汇出金额不能低于50");
			}
			BigDecimal amountIn = detailJO.getBigDecimal("amountIn");
			if (amountIn == null) {
				return R.error("汇入金额不能为空");
			} else if (amountOut.compareTo(BigDecimal.ZERO) < 0) {
				return R.error("汇入金额必须大于0");
			}
		}
		
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setUserId(loginUserId).setStatus(1).queryFirst();
		
		TcwWanliCnyPayment entity = null;
		{
			Integer effectStock = FlowEnum.EffectStock.NOT_EFFECT.value;
			Long createChangeId = tsUserChange.getId();
			entity = TcwWanliCnyPayment.tcwWanliCnyPayment(bid, effectStock, createChangeId, depositPlatformCode, drawingType, remark, 1);
			tcwWanliCnyPaymentMapper.insert(entity);
		}
		
		// 添加万里汇CNY付款单明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			
			String pbid = bid;
			String vgsbm = detailJO.getString("vgsbm");
			String vjylx = detailJO.getString("vjylx");
			String partnerBankInfoVid = detailJO.getString("partnerBankInfoVid");
			String currencyCodeOut = detailJO.getString("currencyCodeOut");
			BigDecimal amountOut = detailJO.getBigDecimal("amountOut");
			BigDecimal exchangeRate = detailJO.getBigDecimal("exchangeRate");
			BigDecimal pencentFeeRatio = detailJO.getBigDecimal("pencentFeeRatio");
			BigDecimal feeOut = detailJO.getBigDecimal("feeOut");
			String currencyCodeIn = "CNY";
			BigDecimal amountIn = detailJO.getBigDecimal("amountIn");
			Integer statePay = PaymentEnum.StatePay.INIT.value;
			TcwWanliCnyPaymentItem tcwWanliCnyPaymentItem = TcwWanliCnyPaymentItem.tcwWanliCnyPaymentItem(pbid, vgsbm, vjylx, partnerBankInfoVid, currencyCodeOut,
					amountOut, exchangeRate, pencentFeeRatio, feeOut, currencyCodeIn, amountIn, statePay, 1);
			tcwWanliCnyPaymentItemMapper.insert(tcwWanliCnyPaymentItem);
		}
		
		/*
		 * 流程初始化
		 */
		YsMenu ysMenu = new YsMenu().setId(menuId).queryFirst();
		if (ysMenu.getFlowModelId().longValue() != 0L) {
			YspModel yspModel = new YspModel().setId(ysMenu.getFlowModelId()).queryFirst();
			String codeModel = yspModel.getCode();
			String createUserId = ShiroUtils.getUserId();
			yspTaskService.init(codeModel, bid, createUserId);
		}
		return R.ok(AddDto.closeAndReload());
	}
	
	@Override
	@Transactional
	public R edit(String bid, String depositPlatformCode, Integer drawingType, String remark, String detailArr, Long menuId) throws Exception {
		
		Integer stateFlow = yspTaskService.flowState(bid);
		if (stateFlow == YsProcInstEnum.StateFlow.FINISH.value) {
			return R.error("已流转结束，无法修改");
		}
		
		/*
		 *  验证详情数据物料
		 *  1、公司编码不能为空
		 *  2、合作商银行账号不能为空
		 *  3、汇出币种不能为空
		 *  4、汇入币种不能为空
		 *  5、汇出金额不能低于50
		 *  6、汇入金额不能为空
		 */
		JSONArray detailJA = JSON.parseArray(detailArr);
		if (detailJA == null || detailJA.size() == 0) {
			return R.error("详情数据不能为空");
		}
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			String vgsbm = detailJO.getString("vgsbm");
			if (vgsbm == null || vgsbm.length() == 0) {
				return R.error("公司编码不能为空");
			}
			String partnerBankInfoVid = detailJO.getString("partnerBankInfoVid");
			if (partnerBankInfoVid == null || partnerBankInfoVid.length() == 0) {
				return R.error("合作商银行账号不能为空");
			}
			String currencyCodeOut = detailJO.getString("currencyCodeOut");
			if (currencyCodeOut == null || currencyCodeOut.length() == 0) {
				return R.error("汇出币种不能为空");
			}
			String currencyCodeIn = detailJO.getString("currencyCodeIn");
			if (currencyCodeIn == null || currencyCodeIn.length() == 0) {
				return R.error("汇入币种不能为空");
			}
			BigDecimal amountOut = detailJO.getBigDecimal("amountOut");
			if (amountOut == null) {
				return R.error("汇出金额不能为空");
			} else if (amountOut.compareTo(new BigDecimal(50)) < 0) {
				return R.error("汇出金额不能低于50");
			}
			BigDecimal amountIn = detailJO.getBigDecimal("amountIn");
			if (amountIn == null) {
				return R.error("汇入金额不能为空");
			} else if (amountOut.compareTo(BigDecimal.ZERO) < 0) {
				return R.error("汇入金额必须大于0");
			}
		}
		
		TcwWanliCnyPayment tcwWanliCnyPayment = new TcwWanliCnyPayment().setBid(bid).queryFirst();
		tcwWanliCnyPayment.setDepositPlatformCode(depositPlatformCode)
			.setDrawingType(drawingType)
			.setRemark(remark);
		tcwWanliCnyPaymentMapper.update(tcwWanliCnyPayment);
		
		// 删除旧的详情数据
		financeMapper.deleteTcwWanliCnyPaymentByPbid(bid);
		
		// 添加万里汇CNY付款单明细
		for (int i = 0; i < detailJA.size(); i++) {
			JSONObject detailJO = detailJA.getJSONObject(i);
			
			String pbid = bid;
			String vgsbm = detailJO.getString("vgsbm");
			String vjylx = detailJO.getString("vjylx");
			String partnerBankInfoVid = detailJO.getString("partnerBankInfoVid");
			String currencyCodeOut = detailJO.getString("currencyCodeOut");
			BigDecimal amountOut = detailJO.getBigDecimal("amountOut");
			BigDecimal exchangeRate = detailJO.getBigDecimal("exchangeRate");
			BigDecimal pencentFeeRatio = detailJO.getBigDecimal("pencentFeeRatio");
			BigDecimal feeOut = detailJO.getBigDecimal("feeOut");
			String currencyCodeIn = "CNY";
			BigDecimal amountIn = detailJO.getBigDecimal("amountIn");
			Integer statePay = PaymentEnum.StatePay.INIT.value;
			TcwWanliCnyPaymentItem tcwWanliCnyPaymentItem = TcwWanliCnyPaymentItem.tcwWanliCnyPaymentItem(pbid, vgsbm, vjylx, partnerBankInfoVid, currencyCodeOut,
					amountOut, exchangeRate, pencentFeeRatio, feeOut, currencyCodeIn, amountIn, statePay, 1);
			tcwWanliCnyPaymentItemMapper.insert(tcwWanliCnyPaymentItem);
		}
		
		return R.ok(EditDto.reloadPage("/web/hr/tcwWanliCnyPayment/toFlow?bid=" + bid));
	}

	@Override
	@Transactional
	public R deleteTrue(Long id) throws Exception {
		if (id == null) {
			return R.error("ID不能为空");
		}
		
		TcwWanliCnyPayment entity = new TcwWanliCnyPayment().setId(id).queryFirst();
		
		Integer stateFlow = yspTaskService.flowState(entity.getBid());
		if (stateFlow != YsProcInstEnum.StateFlow.INIT.value) {
			return R.error("非制单状态，无法修改");
		}
		
		// 验证是否制单人
		String loginUserId = ShiroUtils.getUserId();
		TsUserChange tsUserChange = new TsUserChange().setId(entity.getCreateChangeId()).queryFirst();
		
		if (!tsUserChange.getUserId().equals(loginUserId)) {
			return R.error("非制单人，无法删除");
		}
		
		// 删除主数据
		tcwWanliCnyPaymentMapper.deleteTrue(id);
		
		// 删除子数据
		List<TcwWanliCnyPaymentItem> listDetail = new TcwWanliCnyPaymentItem().setPbid(entity.getBid()).queryList();
		for(TcwWanliCnyPaymentItem detail : listDetail) {
			tcwWanliCnyPaymentItemMapper.deleteTrue(detail.getId());
		}
		
		yspTaskService.flowDelete(entity.getBid(), loginUserId);
		return R.ok();
	}

	@Override
	@Transactional
	public R flowPass(String bid, String loginUserId) throws Exception {
		
		try {
			Flow f = yspTaskService.flowPass(bid, loginUserId);
			if (f.getCode() == Flow.Code.FAILED.value) {
				return R.error(f.getMsg());
			} else {
				
				if (f.getState() == Flow.State.FINISH.value) {
					flowFinish(bid);
				}
				return R.ok();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return R.error("服务器正在开小差，请联系客服");
		}
	}

	@Override
	public R flowRefuse(String bid, String reason, String loginUserId) throws Exception {
		
		R r = yspTaskService.flowRefuse(bid, reason, loginUserId);
		return r;
	}

	@Override
	@Transactional
	public void flowFinish(String bid) throws Exception {

		TcwWanliCnyPayment entity = new TcwWanliCnyPayment().setBid(bid).queryFirst();
		
		YsProcInst ysProcInst = new YsProcInst().setBid(entity.getBid()).queryFirst();
		if (ysProcInst.getStateFlow() != YsProcInstEnum.StateFlow.FINISH.value) {
			return;
		}
		
		entity.setEffectStock(FlowEnum.EffectStock.EFFECTED.value);
		tcwWanliCnyPaymentMapper.update(entity);
		
		List<TcwWanliCnyPaymentItem> listTcwWanliCnyPaymentItem = new TcwWanliCnyPaymentItem().setPbid(bid).queryList();
		for(TcwWanliCnyPaymentItem tcwWanliCnyPaymentItem : listTcwWanliCnyPaymentItem) {
			Long wanliCnyPaymentItemId = tcwWanliCnyPaymentItem.getId();
			tcwWanliPayoutService.addPayOfCnyPayment(wanliCnyPaymentItemId);
		}
	}

	@Override
	public void paySuccess(Long id) throws Exception {
		TcwWanliCnyPaymentItem tcwWanliCnyPaymentItem = new TcwWanliCnyPaymentItem().setId(id).queryFirst();
		tcwWanliCnyPaymentItem.setStatePay(PaymentEnum.StatePay.SUCCESS.value);
		tcwWanliCnyPaymentItemMapper.update(tcwWanliCnyPaymentItem);
	}

	//获取列表数据
	@Override
	@Transactional
	public Map<String,Object> getExtraParam( String bid) throws Exception{
		Map<String, Object> extraParam = new TcwWanliCnyPayment()
				.setBid(bid)

				.addLeftJoin("TCW_DepositPlatform B ON B.Code = A.DepositPlatformCode")
				.addField("B.PlatformName platformName")
				.addField("B.Code depositPlatformCode")
				.addField("B.Name depositPlatformName")

				.addLeftJoin("TB_CompanyInfo C ON C.Vid = B.CompanyVid")
				.addField("C.Vid companyVid")
				.addField("C.Vname companyVname")
				.queryFirstMap();
		return extraParam;
	}
	//获取子列表数据
	@Override
	@Transactional
	public List<Map<String, Object>> getItemList( String bid) throws Exception{
		List<Map<String, Object>> sonlist = new TcwWanliCnyPaymentItem()
				.setPbid(bid)
				.addLeftJoin("THR_OperateCompanyApply B on B.Vgsbm = A.Vgsbm")
				.addField("B.Vgsjc vgsjc")

				.addLeftJoin("TCW_PartnerBankInfo C on C.Vid = A.PartnerBankInfoVid")
				.addField("C.Vyhzhmc partnerBankInfoVyhzhmc")
				.addField("C.Vyhzh partnerBankInfoVyhzh")
				.addField("C.Vkhh partnerBankInfoVkhh")

				.queryMap();
		return sonlist;
	}


}
